package org.thss.petri.gef.commands;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;

import org.eclipse.gef.commands.Command;
import org.thss.petri.model.Arc;
import org.thss.petri.model.Node;
import org.thss.petri.model.PetriNet;
import org.thss.petri.model.Place;
import org.thss.petri.model.Token;
import org.thss.petri.model.Transition;
import org.thss.petri.model.impl.TransitionImpl;

public class FirePetriNetCommand extends Command {
	private PetriNet net;
	private FireTransitionCommand fireCommand;
	
	public void setNet(PetriNet net){
		this.net = net;
	}
	
	/**
	 * If more than one transition is enabled, return true
	 */
	@Override
	public boolean canExecute() {
		if (net == null) {
			return false;
		}
		List<Transition> list = getEnableTransitionList();
		if(list.size() == 0){
			return false;
		}
		return true;
	}

	/**
	 * Randomly fire a transition
	 */
	@Override
	public void execute() {
		List<Transition> list = getEnableTransitionList();
		Random random = new Random();
		int index = Math.abs(random.nextInt()) % list.size();
		Transition transition = list.get(index);
		fireCommand = new FireTransitionCommand();
		fireCommand.setTransition(transition);
		fireCommand.execute();
	}
	
	/**
	 * Get all enabled transition list
	 * @return
	 */
	private List<Transition> getEnableTransitionList() {
		List<Transition> list = new ArrayList<Transition>();
		
		for (Node node : net.getNodes()) {
			if (node instanceof Transition && ((Transition) node).isEnabled()) {
				list.add((Transition)node);
			}
		}
		
		return list;
	}

	@Override
	public void redo() {
		if (fireCommand != null) {
			fireCommand.redo();
		}
	}

	@Override
	public void undo() {
		if (fireCommand != null) {
			fireCommand.undo();
		}
	}

}
